﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//using DG.Tweening;
using QxFramework.Utilities;

public class GetMouse : MonoSingleton<GetMouse>, IEventListener
{
    private LayerMask mask;
    public bool ClickAllowed;
    public RaycastHit hitinfo;
    private CreatureData creature;
    private Object data;
    private Equipment equipment;
    private GameObject PickAudio = GameObject.Find("AudioPlayer/PickAudio");
    //public DiceData temp;
    //private GameObject suface;
    public bool IsCrystal;

    private void Awake()
    {
        Initiate();
    }
    private void Start()
    {
        EventNodeCore.GetInstance().AttachEventListener(EventDef.Steady, this);
    }
    public void Initiate()
    {
        ClickAllowed = false;
        IsCrystal = false;
    }

    private void OnDestroy()
    {
        if (EventNodeCore.GetInstance())
        {
            EventNodeCore.GetInstance().DetachEventListener(EventDef.Steady, this);
        }
    }

    void Update()
    {
        if (ClickAllowed)
        {
            MouseClick();
        }
    }

    private void MouseClick() // TODO 彻底改成获取操作信息后发送给Core
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {

            Debug.Log("Click");

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            //mask = 1 << (LayerMask.NameToLayer("Ground"));
            if (Physics.Raycast(ray, out hitinfo, 500/*, mask.value*/))
            {
                Debug.Log("点击选中" + hitinfo.transform.name);

                Debug.DrawLine(ray.origin, hitinfo.point, Color.red, 5.0f);

                bool IsActed = false; // 记录行动有效
                int messageTypeSent = 2147483647; // 准备发送的操作类型
                object messageSent = null; // 准备发送的数据

                GameObject hitGObj = hitinfo.collider.gameObject; // 选中物体

                // 判断与执行操作，先要判断点中目标是否相邻，相邻且可行动则再判断点中目标的行动类型
                switch (hitGObj.tag)
                {
                    case "Dice":
                        DiceController hitGround = hitGObj.GetComponent<DiceController>();
                        GameObject ObjectOfGround = hitGround.Data.ObjectOfGround; //地面上的物体
                        if (ObjectOfGround == null) 
                        {
                            // TODO 刷新一次地面的物体登记再看一下是否为空,有点麻烦，暂时不要做
                            goto case "JustForMove";
                        } // 空地面
                        else if (ObjectOfGround.tag != "Player") 
                        {
                            if (!ObjectOfGround.activeSelf)
                            {
                                goto case "JustForMove";
                            } // 没有激活说明没东西
                            if (ObjectOfGround.tag == "Item") 
                            {
                                hitGObj = ObjectOfGround;
                                goto case "JustForMove";
                            } // 道具
                            else if (ObjectOfGround.tag == "Enemy")
                            {
                                Debug.Log("hit" + ObjectOfGround.name);
                                hitGObj = ObjectOfGround;
                                goto case "Enemy";

                            } // 敌人
                            else if (ObjectOfGround.tag == "Block")
                            {
                                hitGObj = ObjectOfGround;
                                goto case "Block";
                            } // Block
                            else if (ObjectOfGround.tag == "Door")
                            {
                                hitGObj = ObjectOfGround;
                                goto case "JustForMove";
                            } // 门
                            else if(ObjectOfGround.tag == "Crystal")
                            {
                                hitGObj = ObjectOfGround;
                                goto case "Crystal";
                            }
                            else Debug.LogWarning("地面" + hitGround.Data.DiceCoordinate + "." + hitGround.Data.GroundTowards + "上登记物品错误！" + ObjectOfGround.name);
                        } // 有东西的地面但不是角色
                        break;
                    case "JustForMove":
                        hitGround = hitGObj.GetComponent<DiceController>();
                        if(hitGround)
                        if (RotateBase.Adjoin(PlayerManager.Instance.Data.CoorDinate, hitGround.Data)) // 可以行动
                        {
                            // 记录移动指令
                            messageTypeSent = EventDef.PlayerMove;
                            messageSent = hitGround.Data;
                            IsActed = true;
                            //Debug.Log("输入角色移动信号: " + messageSent);
                        }
                        break;
                    case "Enemy":
                        // 有关敌人的处理和记录攻击指令
                        if (RotateBase.Adjoin(PlayerManager.Instance.Data.CoorDinate, hitGObj.GetComponent<CreatureData>().CoorDinate)) // 可以行动
                        {
                            // 记录攻击指令
                            messageTypeSent = EventDef.PlayerAtk;
                            messageSent = hitGObj;
                            //生物类数据
                            IsActed = true;
                            Debug.Log("输入角色攻击信号: " + messageSent);
                        }
                        break;
                    case "Item":
                        // 有关道具的处理
                        if (hitGObj.GetComponent<ItemBase>())
                        {
                            hitGObj.GetComponent<ItemBase>().IsActed = true;
                        }
                        hitGObj = hitGObj.transform.parent.parent.gameObject;
                        Debug.LogWarning("1");
                        EventNodeCore.GetInstance().SendMessage(-EventDef.PickSomeThing, null, hitGObj);
                        Debug.LogWarning("Pick Something");

                        goto case "JustForMove";
                    case "Block":
                        // 有关挡路的东西的处理，是互动还是不互动，记录互动指令或者行动无效（正式版本需要播放一次玩家移动但是卡住的动画，所以需要临时指定下一回合是PlayerBlocked回合）
                        break;                 
                    case "Crystal":
                        //捡到晶体
                        if (!IsCrystal)
                        {
                            Debug.Log("唯一一次，点击中晶体");
                            EventNodeCore.GetInstance().SendMessage(EventDef.PickCrystal);
                            IsCrystal = true;
                            IsActed = true;
                            Destroy(hitGObj);
                        }
                        else
                        {
                            goto case "Item";
                        }
                        break;
                    default://其他
                        Debug.Log("点击无效,点击目标名： " + hitinfo.collider.gameObject.name);
                        break;
                }

                if (IsActed)
                {
                    Debug.LogWarning(messageTypeSent);
                    EventNodeCore.GetInstance().HandleEvent(messageTypeSent, messageSent,null); // 发送行动消息                  
                    RegistAction(-1); // 注销
                    ClickAllowed = false;
                } // 行动
            }
        }
    }

    ///// <summary>
    ///// 间隔一段时间后回收门，现在的算法马上回收有问题
    ///// </summary>
    ///// <param name="ObjectOfGround"></param>
    ///// <returns></returns>
    //IEnumerator Return(GameObject ObjectOfGround)
    //{
    //    yield return new WaitForSeconds(1.0f);
    //    ObjectPool.GetInstance().Return(ObjectOfGround);
    //}


    public bool HandleEvent(int id, object param1, object param2)
    {
        if (id == EventDef.Steady) // 实现等待玩家输入操作
        {
            ClickAllowed = true;
            RegistAction(1);
        }
        return false;
    }

    public int EventPriority()
    {
        return 0;
    }
    /// <summary>
    /// 注册行动或注销
    /// </summary>
    /// <param name="IsR">1为注册，-1为注销</param>
    private void RegistAction(int IsR)
    {
        EventNodeCore.GetInstance().HandleEvent(EventDef.Action * IsR, null, null);
    }

}

/*
 * 获取鼠标点击，判断点击对象，调用PlayerRunner中的各个行动方法
 * 点击需要GameManager许可
 * 拖动鼠标移动视角
 * 拖动不需要Gamemanager许可
 */

